home *** CD-ROM | disk | FTP | other *** search
- real twoPi, dt2, normal, b0, b1, a0, a1, int1, int0;
- real loFreq, hiFreq, x, p, z;
- integer phOut, divOut, oldState, oldVCOstate, oldSq, phPulse;
- integer numClks;
-
-
- procedure
- pllCirc();
-
- integer
- pllComp(integer change);
-
- integer
- checkPLL()
- {
- twoPi = 2.0*PI;
- ** first check data
- if (novalue(bandwidth+damp+divider+vcolow+vcohi))
- return(1);
- if (bandwidth <= 0.0 || divider < 1.0 || divider > 1000000000.0
- || damp < 0.1 || VCOLow < 0.0 || VCOHi < 0.0)
- return(1);
- if (pllComp(FALSE))
- return(2);
- return(FALSE);
- }
-
-
- ** This message occurs for each step in the simulation.
- on simulate
- {
- pllCirc();
-
- ** sysGlobal2 is the file reference number for the DEBUG TRACE
- if( sysGlobal2 != 0.0 ) ** 0 is error, check for open file for TRACE
- {
- // template for report: |BLOCK NAME *****************|block number |BLOCK NUMBER*******
- fileWrite(sysGlobal2,"Phase Locked Loop block number "+(MyBlockNumber())+". Current Time:"+currentTime+".","",True);
- if(getBlockLabel(myBlockNumber()) != "")
- fileWrite(sysGlobal2,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
- fileWrite(sysGlobal2," In = "+InputIn,"",True);
- fileWrite(sysGlobal2," Freq Out = "+FreqOut,"",True);
- fileWrite(sysGlobal2," Demod Out = "+DemodOut,"",True);
- fileWrite(sysGlobal2," Phase Out = "+PhaseOut,"",True);
- fileWrite(sysGlobal2," ","",True);
- }
- }
-
- on endSim
- {
- ** sysGlobal1 is the file reference number for the TEXT REPORT
- if( sysGlobal1 != 0.0 ) ** 0 is error, check for open file for REPORT
- {
- // template for report: |BLOCK NAME *****************|block number |BLOCK NUMBER*******
- fileWrite(sysGlobal1,"Phase Locked Loop block number "+(MyBlockNumber()),"",True);
- if(getBlockLabel(myBlockNumber()) != "")
- fileWrite(sysGlobal1,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
- fileWrite(sysGlobal1," Bandwidth = "+bandwidth,"",True);
- fileWrite(sysGlobal1," Damping = "+damp,"",True);
- fileWrite(sysGlobal1," Frequency Multiplier = "+Divider,"",True);
- fileWrite(sysGlobal1," VCO Low Limit = "+VCOLow,"",True);
- fileWrite(sysGlobal1," VCO High Limit = "+VCOHi,"",True);
- if (passive)
- fileWrite(sysGlobal1," Passive loop filter","",True);
- else
- fileWrite(sysGlobal1," Active loop filter","",True);
- if (exor)
- fileWrite(sysGlobal1," Exclusive-Or detector","",True);
- else if (Tri)
- fileWrite(sysGlobal1," Frequency Tri-State","",True);
- else
- fileWrite(sysGlobal1," RS Flip Flop","",True);
- if( comments != "" )
- fileWrite(sysGlobal1," Comments = "+comments,"",True);
- fileWrite(sysGlobal1," ","",True);
- }
- }
-
- Procedure
- ErrorCheck()
- {
- integer ret;
-
- ret = checkPLL();
-
- if (ret == 1)
- {
- usererror("Please enter all parameters as positive values in Phase \
- Locked Loop block "+myBlockNumber());
- abort;
- }
- else if (ret == 2)
- {
- usererror("The damping value was too low... changed to 1.1*minimum \
- damping for this configuration in Phase Locked Loop block "
- +myBlockNumber());
- abort;
- }
- }
-
- ** If the dialog data is inconsistent for simulation, abort.
- on OK
- {
- ErrorCheck();
- }
-
-
- ** If the dialog data is inconsistent for simulation, abort.
- on checkdata
- {
- ErrorCheck();
- }
-
- on stepSize
- {
- real temp;
-
- twoPi = 2.0*PI;
- temp = min2(twoPi/20.0*max2(p,z/4.0), 1.0/(hiFreq*20.0));
- if (deltaTime > temp)
- deltaTime = temp;
- }
-
- ** Initialize any simulation variables.
- on initsim
- {
- twoPi = 2.0*PI;
- if (pllComp(FALSE))
- abort;
- }
-
-
- on createBlock
- {
- divider = 1.0;
- }
-
- integer
- pllComp(integer change)
- {
- integer j;
- real temp, pole, zero, w, kv, kd;
- real minDamp, t1, t2;
- integer longD;
-
- dt2 = deltaTime/2.0;
-
- divider = int(divider);
- loFreq = VCOLow;
- hiFreq = VCOHi;
-
- if (loFreq > hiFreq)
- {
- temp = loFreq;
- loFreq = hiFreq;
- hiFreq = temp;
- }
-
- w = twoPi*bandwidth;
-
- ** first, calculate pole, zero from band, damping, vco, divider
- ** calc Kv
- if (exor) ** EXOR
- kd = 1.0/pi;
- else if (tri) ** phase/frequency
- kd = 0.5/twoPi;
- else ** flip flop
- kd = 1.0/twoPi;
-
- kv = kd*twoPi*(hiFreq-loFreq)/divider;
-
- if (passive) ** passive
- {
- minDamp = w/(2.0*kv);
- if (damp < minDamp)
- {
- damp = minDamp*1.1;
- return(TRUE);
- }
- t1 = kv/(w*w);
- t2 = 2.0*damp/w-1.0/kv;
- p = 1.0/t1;
- z = 1.0/t2;
- ** then, warp for simulation
- p = (1.0-exp(-p*dt2))/dt2;
- z = (1.0-exp(-z*dt2))/dt2;
- normal = p/z;
- b0 = 1.0;
- b1 = p;
- a0 = 1.0;
- a1 = z;
- }
- else ** active
- {
- minDamp = 0;
- t1 = kv/(w*w);
- t2 = 2.0*damp/w;
- p = 1.0/t1;
- z = 1.0/t2;
- normal = p;
- a0 = t2/t1;
- }
-
- numClks = 0;
- x = 0.0;
- phOut = 0;
- divOut = 0;
- oldState = 0;
- oldVCOstate = 0;
- oldSq = 0;
- phPulse = 0;
- int0 = 0.0;
- int1 = 0.0;
- return(FALSE);
- }
-
-
- procedure
- pllCirc()
- {
- real eo, demod, p;
- integer sq, sigState, vcoState, state, i, pState;
-
- sigState = inputIn > 0.5;
-
- for (i=0; i<2; i++)
- {
- vcoState = divOut;
-
- ** first, get phase detector output
- if (exor) ** exor phase detector
- {
- pState = FALSE;
- phPulse = TRUE;
- phOut = (sigState != vcoState); ** exor
- }
- else if (tri) ** freq tri-state detector
- {
- pState = TRUE;
- state = oldState; ** save new state
- switch (state) ** last state
- {
- case 0:
- if (sigState && vcoState)
- {
- state = 6;
- phPulse = FALSE;
- }
- else if (sigState)
- {
- state = 5;
- phPulse = FALSE;
- }
- else if (vcoState)
- {
- state = 1;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 1:
- if (sigState)
- {
- state = 6;
- phPulse = FALSE;
- }
- else if (! vcoState)
- {
- state = 0;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 2:
- if (! sigState)
- {
- state = 1;
- phPulse = TRUE;
- phOut = 0.0;
- }
- else if (! vcoState)
- {
- state = 3;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 3:
- if (! sigState)
- {
- state = 0;
- phPulse = TRUE;
- phOut = 0.0;
- }
- else if (vcoState)
- {
- state = 2;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 4:
- if (sigState && vcoState)
- {
- state = 6;
- phPulse = FALSE;
- }
- else if (sigState)
- {
- state = 11;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (vcoState)
- {
- state = 1;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 5:
- if (! sigState)
- {
- state = 4;
- phPulse = FALSE;
- }
- else if (vcoState)
- {
- state = 2;
- phPulse = TRUE;
- phOut = 0.0;
- }
- break;
- case 6:
- if (! sigState)
- {
- state = 7;
- phPulse = FALSE;
- }
- else if (! vcoState)
- {
- state = 5;
- phPulse = FALSE;
- }
- break;
- case 7:
- if (sigState)
- {
- state = 10;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (! vcoState)
- {
- state = 4;
- phPulse = FALSE;
- }
- break;
- case 8:
- if (sigState && vcoState)
- {
- state = 6;
- phPulse = FALSE;
- }
- else if (sigState)
- {
- state = 11;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (vcoState)
- {
- state = 7;
- phPulse = FALSE;
- }
- break;
- case 9:
- if (sigState)
- {
- state = 10;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (! vcoState)
- {
- state = 8;
- phPulse = TRUE;
- phOut = 1.0;
- }
- break;
- case 10:
- if (! sigState)
- {
- state = 9;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (! vcoState)
- {
- state = 11;
- phPulse = TRUE;
- phOut = 1.0;
- }
- break;
- case 11:
- if (! sigState)
- {
- state = 8;
- phPulse = TRUE;
- phOut = 1.0;
- }
- else if (vcoState)
- {
- state = 6;
- phPulse = FALSE;
- }
- break;
- default:
- state = 0;
- phPulse = FALSE;
- break;
- }
- oldState = state; ** save new state
- }
- else ** rs flip-flop
- {
- pState = FALSE;
- phPulse = TRUE;
- if (sigState && ! oldState) ** old sigState
- phOut = 1.0;
- else if (vcoState && ! oldVCOstate) ** old vcoState
- phOut = 0.0;
- oldState = sigState; ** save new state
- oldVCOstate = vcoState; ** save new state
- }
-
- ** then pass thru filter
- if (passive) ** passive filter
- {
- if (phPulse)
- int0 = phOut*normal-int1*b1;
- else
- int0 = 0.0;
- int1 = int1+dt2*int0;
- eo = int0+a1*int1;
- }
- else ** active filter integrator
- {
- if (phPulse)
- p = phOut-0.5;
- else
- p = 0.0;
- int1 += dt2*normal*p;
- demod = int1;
-
- if (demod > 1.0)
- demod = 1.0;
- else if (demod < 0.0)
- demod = 0.0;
- int1 = demod;
- eo = a0*p+demod;
- }
-
- ** damping limit
- if (eo>1.0)
- eo = 1.0;
- else if (eo<0.0)
- eo = 0.0;
-
- ** then get vco output, eo is control
- x = x+dt2*(loFreq+eo*(hiFreq-loFreq));
-
- **if (eo != 0.0)
- ** usererror("x="+x+", eo="+eo+", dt2="+dt2+"loFreq="+loFreq+", hiFreq="+hiFreq);
-
- while (x >= 1.0)
- x -= 1.0;
-
- sq = (x>=0.0 && x<0.5);
-
- ** then get divider output
- if (sq != oldSq)
- {
- numClks++;
- oldSq = sq;
- }
- if (numClks >= divider)
- {
- divOut = ! divOut;
- numClks = 0;
- }
- }
-
- if (pState)
- phaseOut = phPulse;
- else
- phaseOut = 0.0;
- freqOut = sq;
- demodOut = eo;
- }
-
-